<template>
    <div class="p-2">
        <el-row :gutter="20">
            <!-- 部门树 -->
            <el-col :lg="4" :xs="24" style="">
                <el-card shadow="hover">
                    <el-input v-model="deptName" placeholder="请输入部门名称" :prefix-icon="Search" clearable />
                    <el-tree
                        ref="deptTreeRef"
                        class="mt-2"
                        node-key="id"
                        :data="deptOptions"
                        :props="{ label: 'label', children: 'children' } as any"
                        :expand-on-click-node="false"
                        :filter-node-method="filterNode"
                        highlight-current
                        default-expand-all
                        @node-click="handleNodeClick"
                    />
                </el-card>
            </el-col>
            <el-col :lg="20" :xs="24">
                <transition
                    :enter-active-class="proxy?.animate.searchAnimate.enter"
                    :leave-active-class="proxy?.animate.searchAnimate.leave"
                >
                    <div v-show="showSearch" class="mb-[10px]">
                        <el-card shadow="hover">
                            <el-form ref="queryFormRef" :model="queryParams" :inline="true">
                                <el-form-item label="账号" prop="userName" style="width: 220px">
                                    <el-input
                                        v-model="queryParams.userName"
                                        placeholder="请输入账号"
                                        clearable
                                        @keyup.enter="handleQuery"
                                    />
                                </el-form-item>
                                <el-form-item label="手机号码" prop="phonenumber" style="width: 220px">
                                    <el-input
                                        v-model="queryParams.phonenumber"
                                        placeholder="请输入手机号码"
                                        clearable
                                        @keyup.enter="handleQuery"
                                    />
                                </el-form-item>

                                <el-form-item label="状态" prop="status">
                                    <el-select v-model="queryParams.status" placeholder="用户状态" clearable>
                                        <el-option
                                            v-for="dict in sys_normal_disable"
                                            :key="dict.value"
                                            :label="dict.label"
                                            :value="dict.value"
                                        />
                                    </el-select>
                                </el-form-item>
                                <el-form-item label="应用平台" prop="status">
                                    <el-select v-model="queryParams.appIds" placeholder="应用平台" clearable multiple>
                                        <el-option
                                            v-for="app in appOptions"
                                            :key="app.appId"
                                            :label="app.appName"
                                            :value="app.appId as string"
                                        />
                                    </el-select>
                                </el-form-item>
                                <el-form-item label="创建时间" style="width: 308px">
                                    <el-date-picker
                                        v-model="dateRange"
                                        value-format="YYYY-MM-DD HH:mm:ss"
                                        type="daterange"
                                        range-separator="-"
                                        start-placeholder="开始日期"
                                        end-placeholder="结束日期"
                                        :default-time="[
                                            new Date(2000, 1, 1, 0, 0, 0),
                                            new Date(2000, 1, 1, 23, 59, 59)
                                        ]"
                                    ></el-date-picker>
                                </el-form-item>
                                <el-form-item>
                                    <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
                                    <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
                                </el-form-item>
                            </el-form>
                        </el-card>
                    </div>
                </transition>

                <el-card shadow="hover">
                    <template #header>
                        <el-row :gutter="10">
                            <el-col :span="1.5">
                                <el-button
                                    v-has-permi="['system:user:add']"
                                    type="primary"
                                    plain
                                    :icon="Plus"
                                    @click="handleAdd()"
                                    >新增</el-button
                                >
                            </el-col>
                            <el-col :span="1.5">
                                <el-button
                                    v-has-permi="['system:user:edit']"
                                    type="success"
                                    plain
                                    :disabled="single"
                                    :icon="Edit"
                                    @click="handleUpdate()"
                                >
                                    修改
                                </el-button>
                            </el-col>
                            <el-col :span="1.5">
                                <el-button
                                    v-has-permi="['system:user:remove']"
                                    type="danger"
                                    plain
                                    :disabled="multiple"
                                    :icon="Delete"
                                    @click="handleDelete()"
                                >
                                    删除
                                </el-button>
                            </el-col>
                            <el-col :span="1.5">
                                <el-dropdown class="mt-[1px]">
                                    <el-button plain type="info">
                                        更多
                                        <el-icon class="el-icon--right"><arrow-down /></el-icon
                                    ></el-button>
                                    <template #dropdown>
                                        <el-dropdown-menu>
                                            <el-dropdown-item :icon="Download" @click="importTemplate"
                                                >下载模板</el-dropdown-item
                                            >
                                            <!-- 注意 由于el-dropdown-item标签是延迟加载的 所以v-has-permi自定义标签不生效 需要使用v-if调用方法执行 -->
                                            <el-dropdown-item
                                                v-if="checkPermi(['system:user:import'])"
                                                :icon="Top"
                                                @click="handleImport"
                                                >导入数据</el-dropdown-item
                                            >
                                            <el-dropdown-item
                                                v-if="checkPermi(['system:user:export'])"
                                                :icon="Download"
                                                @click="handleExport"
                                                >导出数据</el-dropdown-item
                                            >
                                        </el-dropdown-menu>
                                    </template>
                                </el-dropdown>
                            </el-col>
                            <right-toolbar
                                v-model:show-search="showSearch"
                                :columns="columns"
                                :search="true"
                                @query-table="getList"
                            ></right-toolbar>
                        </el-row>
                    </template>

                    <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
                        <el-table-column type="selection" width="50" align="center" />
                        <el-table-column
                            v-if="columns[0].visible"
                            key="userId"
                            label="用户编号"
                            align="center"
                            prop="userId"
                        />
                        <el-table-column
                            v-if="columns[1].visible"
                            key="userName"
                            label="账号"
                            align="center"
                            prop="userName"
                            :show-overflow-tooltip="true"
                        />
                        <el-table-column
                            v-if="columns[2].visible"
                            key="nickName"
                            label="姓名"
                            align="center"
                            prop="nickName"
                            :show-overflow-tooltip="true"
                        />
                        <el-table-column
                            v-if="columns[3].visible"
                            key="deptName"
                            label="部门"
                            align="center"
                            prop="deptName"
                            :show-overflow-tooltip="true"
                        />
                        <el-table-column
                            v-if="columns[4].visible"
                            key="phonenumber"
                            label="手机号码"
                            align="center"
                            prop="phonenumber"
                            width="120"
                        />
                        <el-table-column
                            v-if="columns[5].visible"
                            key="ifLeader"
                            label="负责人"
                            align="center"
                            prop="ifLeader"
                        >
                            <template #default="scope">
                                <el-tag :type="scope.row.ifLeader ? 'success' : 'info'">{{
                                    scope.row.ifLeader ? '是' : '否'
                                }}</el-tag>
                            </template>
                        </el-table-column>
                        <el-table-column
                            v-if="columns[6].visible"
                            key="isMessageEnabled"
                            label="接收消息"
                            align="center"
                            prop="phonenumber"
                        >
                            <template #default="scope">
                                <el-tag :type="scope.row.isMessageEnabled ? 'success' : 'info'">{{
                                    scope.row.isMessageEnabled ? '是' : '否'
                                }}</el-tag>
                            </template>
                        </el-table-column>
                        <el-table-column
                            v-if="columns[7].visible"
                            key="apps"
                            label="应用平台"
                            align="center"
                            prop="apps"
                        >
                            <template #default="scope">
                                <el-tag v-for="app in scope.row.apps" :key="app.appId">{{ app.appName }}</el-tag>
                            </template>
                        </el-table-column>
                        <el-table-column v-if="columns[8].visible" key="status" label="状态" align="center">
                            <template #default="scope">
                                <el-switch
                                    v-model="scope.row.status"
                                    active-value="0"
                                    inactive-value="1"
                                    @change="handleStatusChange(scope.row)"
                                ></el-switch>
                            </template>
                        </el-table-column>

                        <el-table-column
                            v-if="columns[9].visible"
                            label="创建时间"
                            align="center"
                            prop="createTime"
                            width="160"
                        >
                            <template #default="scope">
                                <span>{{ scope.row.createTime }}</span>
                            </template>
                        </el-table-column>

                        <el-table-column label="操作" fixed="right" width="180" class-name="small-padding fixed-width">
                            <template #default="scope">
                                <el-tooltip v-if="scope.row.userId !== 1" content="修改" placement="top">
                                    <el-button
                                        v-hasPermi="['system:user:edit']"
                                        link
                                        type="primary"
                                        :icon="Edit"
                                        @click="handleUpdate(scope.row)"
                                    ></el-button>
                                </el-tooltip>
                                <el-tooltip v-if="scope.row.userId !== 1" content="删除" placement="top">
                                    <el-button
                                        v-hasPermi="['system:user:remove']"
                                        link
                                        type="primary"
                                        :icon="Delete"
                                        @click="handleDelete(scope.row)"
                                    ></el-button>
                                </el-tooltip>

                                <el-tooltip v-if="scope.row.userId !== 1" content="重置密码" placement="top">
                                    <el-button
                                        v-hasPermi="['system:user:resetPwd']"
                                        link
                                        type="primary"
                                        :icon="Key"
                                        @click="handleResetPwd(scope.row)"
                                    ></el-button>
                                </el-tooltip>

                                <el-tooltip v-if="scope.row.userId !== 1" content="分配角色" placement="top">
                                    <el-button
                                        v-hasPermi="['system:user:edit']"
                                        link
                                        type="primary"
                                        :icon="CircleCheck"
                                        @click="handleAuthRole(scope.row)"
                                    ></el-button>
                                </el-tooltip>
                            </template>
                        </el-table-column>
                    </el-table>

                    <pagination
                        v-show="total > 0"
                        v-model:page="queryParams.pageNum"
                        v-model:limit="queryParams.pageSize"
                        :total="total"
                        @pagination="getList"
                    />
                </el-card>
            </el-col>
        </el-row>

        <!-- 添加或修改用户配置对话框 -->
        <el-dialog
            ref="formDialogRef"
            v-model="dialog.visible"
            :title="dialog.title"
            width="600px"
            append-to-body
            @close="closeDialog"
        >
            <el-form ref="userFormRef" :model="form" :rules="rules" label-width="80px">
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="姓名" prop="nickName">
                            <el-input v-model="form.nickName" placeholder="请输入姓名" maxlength="30" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="归属部门" prop="deptId">
                            <el-tree-select
                                v-model="form.deptId"
                                :data="enabledDeptOptions"
                                :props="{ value: 'id', label: 'label', children: 'children' }"
                                value-key="id"
                                placeholder="请选择归属部门"
                                check-strictly
                                @change="handleDeptChange"
                            />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="手机号码" prop="phonenumber">
                            <el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="邮箱" prop="email">
                            <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item v-if="form.userId == undefined" label="账号" prop="userName">
                            <el-input v-model="form.userName" placeholder="请输入账号" maxlength="30" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
                            <span>系统默认密码</span>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="过期时间" prop="expiredDate">
                            <el-date-picker
                                v-model="form.expiredDate"
                                type="date"
                                placeholder="请选择过期时间"
                                value-format="YYYY-MM-DD HH:mm:ss"
                                style="width: 100%"
                                :disabled-date="date => disabledDate(date)"
                            />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="负责人" prop="ifLeader">
                            <el-radio-group v-model="form.ifLeader">
                                <el-radio :label="true">是</el-radio>
                                <el-radio :label="false">否</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="接收消息" prop="isMessageEnabled">
                            <el-radio-group v-model="form.isMessageEnabled">
                                <el-radio :label="true">接收</el-radio>
                                <el-radio :label="false">不接收</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="应用平台" prop="appIds">
                            <el-select v-model="form.appIds" multiple placeholder="请选择应用平台">
                                <el-option
                                    v-for="app in appOptions"
                                    :key="app.appId"
                                    :label="app.appName"
                                    :value="app.appId as string"
                                />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="用户性别">
                            <el-select v-model="form.sex" placeholder="请选择">
                                <el-option
                                    v-for="dict in sys_user_sex"
                                    :key="dict.value"
                                    :label="dict.label"
                                    :value="dict.value"
                                ></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="状态">
                            <el-radio-group v-model="form.status">
                                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{
                                    dict.label
                                }}</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="岗位">
                            <el-select v-model="form.postIds" multiple placeholder="请选择">
                                <el-option
                                    v-for="item in postOptions"
                                    :key="item.postId"
                                    :label="item.postName"
                                    :value="item.postId"
                                    :disabled="item.status == '1'"
                                ></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="角色" prop="roleIds">
                            <el-select v-model="form.roleIds" filterable multiple placeholder="请选择">
                                <el-option
                                    v-for="item in curAppRoleOptions"
                                    :key="item.roleId"
                                    :label="item.roleName + '(' + appCodeMap.get(item.appCode)?.appName + ')'"
                                    :value="item.roleId"
                                    :disabled="item.status == '1'"
                                ></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="备注">
                            <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitForm">确 定</el-button>
                    <el-button @click="cancel()">取 消</el-button>
                </div>
            </template>
        </el-dialog>

        <!-- 用户导入对话框 -->
        <el-dialog v-model="upload.open" :title="upload.title" width="400px" append-to-body>
            <el-upload
                ref="uploadRef"
                :limit="1"
                accept=".xlsx, .xls"
                :headers="upload.headers"
                :action="upload.url + '?updateSupport=' + upload.updateSupport"
                :disabled="upload.isUploading"
                :on-progress="handleFileUploadProgress"
                :on-success="handleFileSuccess"
                :auto-upload="false"
                drag
            >
                <el-icon class="el-icon--upload">
                    <i-ep-upload-filled />
                </el-icon>
                <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
                <template #tip>
                    <div class="text-center el-upload__tip">
                        <div class="el-upload__tip">
                            <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
                        </div>
                        <span>仅允许导入xls、xlsx格式文件。</span>
                        <el-link
                            type="primary"
                            :underline="false"
                            style="font-size: 12px; vertical-align: baseline"
                            @click="importTemplate"
                            >下载模板</el-link
                        >
                    </div>
                </template>
            </el-upload>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitFileForm">确 定</el-button>
                    <el-button @click="upload.open = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script setup name="User" lang="ts">
import RightToolbar from './components/RightToolbar.vue';
import Pagination from './components/Pagination.vue';
import type { UserForm, UserQuery, UserVO } from '@great/services';
import type { DeptTreeVO, DeptVO, AppVO } from '@great/services';
import type { RoleVO } from '@great/services';
import type { PostVO } from '@great/services';
import { globalHeaders, checkPermi } from '@/utils/ruoyi';
import { to } from 'await-to-js';
import { systemUserService, systemPostService, systemAppService } from '@great/services';
import { useRouter } from 'vue-router';
import type { DateModelType } from 'element-plus';
import { tansParams } from '@/utils/ruoyi';
import {
    ArrowDown,
    Delete,
    Edit,
    Plus,
    Search,
    Top,
    Download,
    CircleCheck,
    Key,
    Refresh
} from '@element-plus/icons-vue';
import type {
    DialogOption,
    ElDialogInstance,
    ElFormInstance,
    ElTreeInstance,
    ElUploadInstance,
    FieldOption,
    ImportOption,
    PageData,
    UploadFile
} from '@/pages/system/system.d';

const router = useRouter();
const { proxy } = getCurrentInstance() as any;
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
const userList = ref<UserVO[]>();
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<number | string>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
const deptName = ref('');
const sys_user_expiredDate = ref<string>();
const deptOptions = ref<DeptTreeVO[]>([]);
const enabledDeptOptions = ref<DeptTreeVO[]>([]);
const postOptions = ref<PostVO[]>([]);
const roleOptions = ref<RoleVO[]>([]);
const curAppRoleOptions = ref<RoleVO[]>([]);
const appOptions = ref<AppVO[]>([]);
const appCodeMap = new Map<string, AppVO>();
// 时间限制
const disabledDate = (date: Date): boolean => {
    const todayStart = new Date();
    todayStart.setHours(0, 0, 0, 0);
    if (date.getTime() <= todayStart.getTime()) return true;
    return false;
};
/*** 用户导入参数 */
const upload = reactive<ImportOption>({
    // 是否显示弹出层（用户导入）
    open: false,
    // 弹出层标题（用户导入）
    title: '',
    // 是否禁用上传
    isUploading: false,
    // 是否更新已经存在的用户数据
    updateSupport: 0,
    // 设置上传的请求头部
    headers: globalHeaders(),
    // 上传的地址
    // url: import.meta.env.VITE_APP_BASE_API + '/system/user/importData'
    url: RUOYI_SERVICE_BASE_URL + '/system/user/importData'
});
// 列显隐信息
const columns = ref<FieldOption[]>([
    { key: 0, label: `用户编号`, visible: false, children: [] },
    { key: 1, label: `账号`, visible: true, children: [] },
    { key: 2, label: `姓名`, visible: true, children: [] },
    { key: 3, label: `部门`, visible: true, children: [] },
    { key: 4, label: `手机号码`, visible: true, children: [] },
    { key: 5, label: `负责人`, visible: true, children: [] },
    { key: 6, label: `接收消息`, visible: true, children: [] },
    { key: 7, label: `应用平台`, visible: true, children: [] },
    { key: 8, label: `状态`, visible: true, children: [] },
    { key: 9, label: `创建时间`, visible: true, children: [] }
]);

const deptTreeRef = ref<ElTreeInstance>();
const queryFormRef = ref<ElFormInstance>();
const userFormRef = ref<ElFormInstance>();
const uploadRef = ref<ElUploadInstance>();
const formDialogRef = ref<ElDialogInstance>();

const dialog = reactive<DialogOption>({
    visible: false,
    title: ''
});

const initFormData: UserForm = {
    userId: undefined,
    deptId: undefined,
    userName: '',
    nickName: undefined,
    phonenumber: undefined,
    email: undefined,
    sex: undefined,
    status: '0',
    remark: '',
    postIds: [],
    roleIds: [],
    expiredDate: '',
    ifLeader: false,
    isMessageEnabled: true,
    appIds: []
};

const initData: PageData<UserForm, any> = {
    form: { ...initFormData },
    queryParams: {
        pageNum: 1,
        pageSize: 10,
        userName: '',
        phonenumber: '',
        status: '',
        deptId: '',
        roleId: '',
        appIds: ''
    },
    rules: {
        userName: [
            { required: true, message: '账号不能为空', trigger: 'blur' },
            {
                min: 2,
                max: 20,
                message: '账号长度必须介于 2 和 20 之间',
                trigger: 'blur'
            }
        ],
        deptId: [{ required: true, message: '归属部门不能为空', trigger: 'blur' }],
        nickName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
        password: [
            { required: false, message: '用户密码不能为空', trigger: 'blur' },
            {
                min: 5,
                max: 20,
                message: '用户密码长度必须介于 5 和 20 之间',
                trigger: 'blur'
            },
            { pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符：< > " \' \\ |', trigger: 'blur' }
        ],
        expiredDate: [{ required: true, message: '有效期不能为空', trigger: 'blur' }],
        ifLeader: [{ required: true, message: '是否负责人不能为空', trigger: 'blur' }],
        isMessageEnabled: [{ required: true, message: '是否接收消息不能为空', trigger: 'blur' }],
        appIds: [{ required: true, message: '应用平台不能为空', trigger: 'blur' }],
        email: [
            {
                type: 'email',
                message: '请输入正确的邮箱地址',
                trigger: ['blur', 'change']
            }
        ],
        phonenumber: [
            {
                pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
                message: '请输入正确的手机号码',
                trigger: 'blur'
            }
        ],
        roleIds: [
            {
                required: true,
                validator: (rule, value) => {
                    if (!form.value.appIds || form.value.appIds.length == 0) {
                        return new Error('请先选择应用平台！');
                    }
                    if (!value || value.length == 0) {
                        return new Error('角色不能为空');
                    }
                    const curAppRoleIds = curAppRoleOptions.value.map(item => item.roleId);
                    if (
                        value.some(val => {
                            return !curAppRoleIds.includes(val);
                        })
                    ) {
                        return new Error('所选角色与应用平台不对应！');
                    }
                    return true;
                },
                trigger: ['blur', 'change']
            }
        ]
    }
};
const data = reactive<PageData<UserForm, UserQuery>>(initData);

const { queryParams, form, rules } = toRefs<PageData<UserForm, any>>(data);

/** 通过条件过滤节点  */
const filterNode = (value: string, data: any) => {
    if (!value) return true;
    return data.label.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
    () => {
        deptTreeRef.value?.filter(deptName.value);
    },
    {
        flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发，此属性控制在DOM元素更新后运行
    }
);

/** 查询用户列表 */
const getList = async () => {
    loading.value = true;
    const res: any = await systemUserService.listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
    loading.value = false;
    userList.value = res.rows;
    total.value = res.total;
};

/** 查询部门下拉树结构 */
const getDeptTree = async () => {
    const res = await systemUserService.deptTreeSelect();
    deptOptions.value = res.data;
    // enabledDeptOptions.value = filterDisabledDept(res.data);
};

/**
 * 递归查找树形结构中的根节点(parentId为0的节点)
 * @param {Array} nodes - 树形结构数组
 * @param {number} startId - 开始查找的节点id
 * @returns {Object|null} - 找到的根节点或null
 */
const nodeMap = new Map(); // 递归遍历所有节点，创建完整的节点映射表
function findRootNode(nodes, startId) {
    // 递归遍历树形结构，收集所有节点
    function traverseTree(treeNodes, disabled = false) {
        treeNodes.forEach(node => {
            if (node.id !== undefined) {
                nodeMap.set(node.id, node);
                node.disabled = disabled || node.disabled;
            }

            // 如果有children，递归遍历子节点
            if (node.children && Array.isArray(node.children)) {
                traverseTree(node.children, node.disabled);
            }
        });
    }
    if (nodeMap.size === 0) {
        // 开始遍历整棵树
        traverseTree(nodes);
    }

    // 递归查找父节点
    function findParent(currentId) {
        const currentNode = nodeMap.get(currentId);
        if (!currentNode) return null;

        // 如果parentId为0，说明找到了根节点
        if (currentNode.parentId === 0 || !nodeMap.has(currentNode.parentId)) {
            return currentNode;
        }

        // 继续查找父节点
        return findParent(currentNode.parentId);
    }

    // 从指定节点开始查找
    return findParent(startId);
}

watchEffect(() => {
    if (!queryParams.value.deptId) return;
    const rootNode = findRootNode(deptOptions.value, queryParams.value.deptId);
    if (!rootNode) return;
    enabledDeptOptions.value = deptOptions.value.filter(dept => {
        if (dept.id != rootNode.id) {
            return false;
        }
        return true;
    });
});

/** 应用列表拉取 */
const getAppList = async () => {
    const res = await systemAppService.appOptionAllList();
    appOptions.value = res.data;
    appCodeMap.clear();
    res.data.forEach(app => {
        appCodeMap.set(app.appCode as string, app);
    });
};

/** 过滤禁用的部门 */
const filterDisabledDept = (deptList: DeptTreeVO[]) => {
    return deptList.filter(dept => {
        if (dept.disabled) {
            return false;
        }
        if (dept.children && dept.children.length) {
            dept.children = filterDisabledDept(dept.children);
        }
        return true;
    });
};

/** 节点单击事件 */
const handleNodeClick = (data: DeptVO) => {
    queryParams.value.deptId = data.id;
    handleQuery();
};

/** 搜索按钮操作 */
const handleQuery = () => {
    queryParams.value.pageNum = 1;
    getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
    dateRange.value = ['', ''];
    queryFormRef.value?.resetFields();
    queryParams.value.pageNum = 1;
    // queryParams.value.deptId = undefined;
    queryParams.value.appIds = undefined;
    // deptTreeRef.value?.setCurrentKey(undefined);
    handleQuery();
};

/** 删除按钮操作 */
const handleDelete = async (row?: UserVO) => {
    const userIds = row?.userId || ids.value;
    const [err] = await to(proxy?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项？') as any);
    if (!err) {
        await systemUserService.delUser(userIds);
        await getList();
        proxy?.$modal.msgSuccess('删除成功');
    }
};

/** 用户状态修改  */
const handleStatusChange = async (row: UserVO) => {
    let text = row.status === '0' ? '启用' : '停用';
    try {
        await proxy?.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?');
        await systemUserService.changeUserStatus(row.userId, row.status);
        proxy?.$modal.msgSuccess(text + '成功');
    } catch (err) {
        row.status = row.status === '0' ? '1' : '0';
    }
};
/** 跳转角色分配 */
const handleAuthRole = (row: UserVO) => {
    const userId = row.userId;
    router.push('/system/user/auth/role/' + userId);
};

/** 重置密码按钮操作 */
const handleResetPwd = async (row: UserVO) => {
    ElMessageBox.confirm(`确认重置用户${row?.userName || ''}的密码为默认密码吗？`, '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
    })
        .then(async () => {
            await systemUserService.resetUserPwd(row.userId);
            proxy?.$modal.msgSuccess('重置成功');
        })
        .catch(() => {});
};

/** 选择条数  */
const handleSelectionChange = (selection: UserVO[]) => {
    ids.value = selection.map(item => item.userId);
    single.value = selection.length != 1;
    multiple.value = !selection.length;
};

/** 导入按钮操作 */
const handleImport = () => {
    upload.title = '用户导入';
    upload.open = true;
};
/** 导出按钮操作 */
const handleExport = () => {
    systemUserService.downloadUser(tansParams({ ...queryParams.value }) as any);
};
/** 下载模板操作 */
const importTemplate = () => {
    systemUserService.downloadTemplate();
};

/**文件上传中处理 */
const handleFileUploadProgress = () => {
    upload.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response: any, file: UploadFile) => {
    upload.open = false;
    upload.isUploading = false;
    uploadRef.value?.handleRemove(file);
    ElMessageBox.alert(
        `<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'> ${response.msg}</div>`,
        '导入结果',
        {
            dangerouslyUseHTMLString: true
        }
    );
    getList();
};

/** 提交上传文件 */
function submitFileForm() {
    uploadRef.value?.submit();
}

/** 重置操作表单 */
const reset = () => {
    form.value = { ...initFormData };
    userFormRef.value?.resetFields();
};
/** 取消按钮 */
const cancel = () => {
    dialog.visible = false;
    reset();
};

/** 新增按钮操作 */
const handleAdd = async () => {
    reset();
    form.value.expiredDate = sys_user_expiredDate.value;
    const { data } = await systemUserService.getUser();
    dialog.visible = true;
    dialog.title = '新增用户';
    postOptions.value = data.posts;
    roleOptions.value = data.roles;
};

/** 修改按钮操作 */
const handleUpdate = async (row?: UserForm) => {
    reset();
    const userId = row?.userId || ids.value[0];
    const { data } = await systemUserService.getUser(userId);
    dialog.visible = true;
    dialog.title = '修改用户';
    Object.assign(form.value, data.user);
    postOptions.value = data.posts;
    roleOptions.value = data.roles;
    form.value.postIds = data.postIds;
    form.value.roleIds = data.roleIds;
    form.value.appIds = (data.user.apps || []).map(app => app.appId as string);
    form.value.expiredDate = form.value.expiredDate || sys_user_expiredDate.value;
};

/** 根据所选appIds筛选对应平台的roleOptions */
watchEffect(() => {
    if (!form.value.appIds || form.value.appIds.length === 0) {
        curAppRoleOptions.value = []; // roleOptions.value;
        return;
    }
    const filteredRoles = roleOptions.value.filter(role => {
        return form.value.appIds?.some(appId => appId === appCodeMap.get(role.appCode)?.appId);
    });
    curAppRoleOptions.value = filteredRoles;
});

watch(
    () => form.value.appIds,
    () => {
        userFormRef.value?.validateField('roleIds');
    },
    { flush: 'post' }
);

/** 提交按钮 */
const submitForm = () => {
    userFormRef.value?.validate(async (valid: boolean) => {
        if (valid) {
            form.value.userId
                ? await systemUserService.updateUser(form.value)
                : await systemUserService.addUser(form.value);
            proxy?.$modal.msgSuccess('操作成功');
            dialog.visible = false;
            await getList();
        }
    });
};

/**
 * 关闭用户弹窗
 */
const closeDialog = () => {
    dialog.visible = false;
    resetForm();
};

/**
 * 重置表单
 */
const resetForm = () => {
    userFormRef.value?.resetFields();
    userFormRef.value?.clearValidate();

    form.value.id = undefined;
    form.value.status = '1';
};
onMounted(() => {
    getDeptTree().then(() => {
        if (deptOptions.value.length > 0) {
            deptTreeRef.value?.setCurrentKey(deptOptions.value[0].id);
            queryParams.value.deptId = deptOptions.value[0].id;
            getList(); // 初始化列表数据, 默认选择第一个节点
        } else {
            loading.value = false;
        }
    }); // 初始化部门数据

    getAppList(); // 拉取应用数据

    proxy?.getConfigKey('sys.user.expiredDate').then((res: any) => {
        sys_user_expiredDate.value = res?.data + ' 00:00:00';
    });
});

async function handleDeptChange(value: number | string) {
    const response = await systemPostService.optionselect(value);
    postOptions.value = response.data;
    form.value.postIds = [];
}
</script>
